#ifndef CLIENT_H
#define CLIENT_H
#include "Card.h"
#include "SimpleCrypt.h"
#include <QTcpSocket>
class Player;
class game;
class Client : public QObject
{
        Q_OBJECT

signals:
    void updateModel();

public:
    /** \brief The Client's constructor.
        * \param nif is QString which will be used to identify the client locally.
        * \param _gm is a pointer to a GameMaster object which will be used to pass messages back. */
    Client(const QString &nif = "", game *_g = 0, QString ip = "0.0.0.0", QString port = "0000", QString type = "AI");
	
    ~Client();
	
    //static QString user;
    QString user;

    /** \brief Makes sure that the client is connected to a host, and establishes a connection if it isn't. */
    void restoreConnection();

    /** \brief Returns the integer representation of a player by searching for their name.
        * \param name is a QString which is the name of the player to search for. */
    int getUserByName( QString name);

public slots:
    /** \brief Can be used to change the name of the client locally.
        * \param nif is a QString which will become the new client ID. */
    void setUserLogged(const QString &nif) { user = nif; }

    /** \brief Requests permission from the server to join the currently hosted game.
        * \param client is a QTcpSocket client to which JSON encoded messages will be sent.
        * \param name is a QString which identifies the screen name of the client. */
    bool requestJoin();

    /** \brief Requests permission from the server to make a change to the screen name.
        * \param new_name is a QString which will become the new client identifier. */
    bool requestNewName(QString new_name);

    /** \brief Requests permission from the server to change team and orientation.
        * \param dir is a QString which identifies the slot the client wants to change to. */
    bool requestSlotChange(QString dir);

    /** \brief Sends the local player's selected bid to the server.
        * \param bid_action is a QString which indicates which bidding action the client will perform.
        * \param count is an int which tells the server how many tricks the client bids.
        * \param trump_suite is a QString which identifies a trump suit if the client has selected one. */
    bool sendBid(QStringList list);

    /** \brief Sends an acknowledge message with relevant error information to the server.
        * \param success is an int which identifies whether or not an error has occurred.
        * \param error_code is an int which identifies which error has occurred. */
    bool sendAcknowledge(int success, int error_code);

    /** \brief Sends the card information that the client has chosen to play to the server.
        * \param suit is a QString which identifies which suit the card belongs to.
        * \param value is a QString which indicates the what card in the suit the player has played. */
    bool sendPlayCard(QString suit, QString value);

    /** \brief Sends a quit message to the server indicating that the client will be leaving the game. */
    bool sendQuit();

    /** \brief Sends the client's response to a fatal error to the server.
        * \param error_msg is a QString describing the nature of the error which has occurred. */
    bool sendError(QString error_msg);

    /** \brief Returns whether or not the client is connected to a host. */
    bool isConnected() { return is_connected; }

    bool sendMove(Card card);

private slots:
    /** \brief The connected slot is triggered when the client has established connection to a host. */
    void connected();
	
	/** \brief If the client receives a message, readMsg is triggered to parse the message. */
    void readMsg();

    /** \brief Deals with functionality regarding what happens when the client disconnects from the server. */
    void connectionClosedByServer();

    /** \brief Closes the connection to the server, without alerting the server first. */
    void closeSocket();

private:
    //static QString IP;

    //static int PORT;
	
    QTcpSocket *socket;

    game *gui;

    bool is_connected;

    Player *player;

    QString ip_address;

    int port;

    QStringList player_list;

    bool gameInProgress;

    SimpleCrypt *crypto;

    /** \brief Writes the JSON object to the tcpsocket.
        * \param json is a QJsonObject which contains the details of the message to be sent to the server. */
    bool writeJSON(QJsonObject json);
};

#endif // CLIENT_H
